package com.littleken.foodieApi.job;

import com.littleken.foodieService.OrderService;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

@Component
public class OrderJob {

    private static final Logger logger = LoggerFactory.getLogger(OrderJob.class);

    @Resource
    private OrderService orderService;

    @Resource
    private RedissonClient redissonClient;

    /**
     * 使用定时任务关闭超期未支付订单，会存在的弊端：
     * 1. 会有时间差，程序不严谨
     * 10:39下单，11:00检查不足1小时，12:00检查，超过1小时多余39分钟
     * 2. 不支持集群
     * 单机没毛病，使用集群后，就会有多个定时任务
     * 解决方案：只使用一台计算机节点，单独用来运行所有的定时任务
     * 3. 会对数据库全表搜索，及其影响数据库性能：select * from order where orderStatus = 10;
     * 定时任务，仅仅只适用于小型轻量级项目，传统项目
     * <p>
     * 后续课程会涉及到消息队列：MQ-> RabbitMQ, RocketMQ, Kafka, ZeroMQ...
     * 延时任务（队列）
     * 10:12分下单的，未付款（10）状态，11:12分检查，如果当前状态还是10，则直接关闭订单即可
     */

//    @Scheduled(cron = "0/3 * * * * ?")
//    @Scheduled(cron = "0 0 0/1 * * ?")
    public void autoCloseOrder() {
        //分布式锁 redis先查有没有其他服务已经启动(已经上锁)，有就不执行，没有就执行
        RLock foodie_key = redissonClient.getLock("foodie_key");
        if (foodie_key.isLocked()){
            return;
        }
        //上锁
        foodie_key.lock(100, TimeUnit.SECONDS);
        orderService.closeOrder();
        logger.debug("执行定时任务，当前时间为：{}", LocalDateTime.now().toString());
    }

}
